package mm.front.jsf.mb;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import mm.back.entity.DetalleVenta;
import mm.back.entity.Producto;
import mm.back.entity.Vendedor;
import mm.back.entity.Venta;
import mm.back.filtros.ProductosFiltro;
import mm.back.service.ProductoService;
import mm.back.service.VendedorService;
import mm.back.service.VentasService;
import mm.back.utils.VentasUtils;
import mm.exceptions.MMGenericException;
import mm.exceptions.MMInvalidIDException;
import mm.front.jsf.ConstantesOutcome;
import mm.front.jsf.JSFUtils;

public class VentasManagedBean implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -7321963004580240028L;

	private ProductoService productoService;
	
	private VendedorService vendedorService;
	
	private VentasService ventasService;
	
	private List<Producto> listaProductos;
	
	private List<DetalleVenta> detalleVenta;
	
	private Vendedor vendedor;
	
	private Long prodToAdd;
	
	private Long prodToDelete;
	
	private Venta venta;
	
	private ProductosFiltro filtroProductos;
	
	public VentasManagedBean() {
		
	}
	
	public String nuevaVenta(){
		reset();
		setFiltroProductos(null);
		return ConstantesOutcome.VENTAS_NUEVA;
	}
	
	public void addProductos(Long id){
		
		if (!VentasUtils.containsProduct(id, getDetalleVenta())){
			Producto p = productoService.getProducto(id);
			
			DetalleVenta dv = new DetalleVenta();
			dv.setProducto(p);
			dv.setCantidad(BigDecimal.ONE);
			dv.setPrecioCompra(p.getPrecioCompra());
			dv.setPrecioVenta(p.getPrecioVenta());
			
			getDetalleVenta().add(dv);
		}
		
	}
	
	public void addProd(){
		if (getProdToAdd() != null){
			addProductos(getProdToAdd());
		}
	}
	
	public void buscarProductosActivos(){
		 getFiltroProductos().setActivo(true);
		 getFiltroProductos().setRubroActivo(Boolean.TRUE);
		 List<Producto> productos = productoService.getProductos(getFiltroProductos());
		 setListaProductos(productos);
	}
	
	
	public void cargarVendedor(){
		
		try {
			if(getVendedor().getId() != null && getVendedor().getId() > 0){
				Vendedor vend = vendedorService.getVendedor(getVendedor().getId());
				if (vend != null){
					
					if(!vend.getActivo()){
						JSFUtils.addErrorMessage("El número de vendedor ingresado no corresponde a un vendedor activo.");
						setVendedor(null);
					}else{
						setVendedor(vend);
					}
				} 
			} else {
				JSFUtils.addErrorMessage("Ingrese el número de vendedor en el campo \"número de vendedor\" para poder seleccionarlo.");
				setVendedor(null);
			}
		} catch (MMGenericException e) {
			FacesMessage fm = new FacesMessage(e.getMessage());
			setVendedor(null);
			fm.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, fm);
		}
	}
	
	public void cambiarVendedor(){
		setVendedor(new Vendedor());
	}
	
	public void quitarProducto(){
		VentasUtils.borrarProducto(prodToDelete, getDetalleVenta());
	}
	
	
	public void cerrarVenta(){
		
		getVenta().setVendedor(getVendedor());
		Set<DetalleVenta> dv = new HashSet<DetalleVenta>(getDetalleVenta());
		getVenta().setDetalleVenta(dv);
		getVenta().setFecha(new Date());
		getVenta().setTotal(getVentaTotal());
		
		try {
			ventasService.registrarVenta(venta);
			
			FacesMessage fm = new FacesMessage("Se registro con exito la venta #" + venta.getId());
			fm.setSeverity(FacesMessage.SEVERITY_INFO);
			FacesContext.getCurrentInstance().addMessage(null, fm);
			
			reset();
			
		} catch (MMGenericException e) {
			FacesMessage fm = new FacesMessage(e.getMessage());
			fm.setSeverity(FacesMessage.SEVERITY_ERROR);
			FacesContext.getCurrentInstance().addMessage(null, fm);
		}
		
	}
	
	
	
	public String viewDetalleVenta(Long id){
		try{
			Venta v = ventasService.buscarVenta(id);
			if (v == null){
				throw new MMInvalidIDException("No se puede recuperar la venta número: "+id);
			}
//			detalleVentaDTO.setVenta(v);
		} catch (MMInvalidIDException mmiie) {
			FacesMessage fm = new FacesMessage("No se puede recuperar la venta número: "+id);
			fm.setSeverity(FacesMessage.SEVERITY_INFO);
			FacesContext.getCurrentInstance().addMessage(null, fm);
			return null;
		}
		return ConstantesOutcome.VENTAS_DETALLE;
	}
	
	public void refresh(){}
	
	private void reset(){
		
		setVenta(null);
		setListaProductos(null);
		setDetalleVenta(null);
		
	}
	
	public BigDecimal getVentaTotal(){
		return VentasUtils.total(getDetalleVenta());
	}

	/**
	 * @param productosService the productosService to set
	 */
	public void setProductoService(ProductoService productoService) {
		this.productoService = productoService;
	}

	/**
	 * @return the prodToAdd
	 */
	public Long getProdToAdd() {
		return prodToAdd;
	}

	/**
	 * @param prodToAdd the prodToAdd to set
	 */
	public void setProdToAdd(Long prodToAdd) {
		this.prodToAdd = prodToAdd;
	}

	/**
	 * @return the filtroProductos
	 */
	public ProductosFiltro getFiltroProductos() {
		if (filtroProductos == null){
			filtroProductos = new ProductosFiltro();
			filtroProductos.setRubroActivo(Boolean.TRUE);
		}
		return filtroProductos;
	}

	/**
	 * @param filtroProductos the filtroProductos to set
	 */
	public void setFiltroProductos(ProductosFiltro filtroProductos) {
		this.filtroProductos = filtroProductos;
	}

	/**
	 * @return the listaProductos
	 */
	public List<Producto> getListaProductos() {
		if (listaProductos == null){
			listaProductos = new ArrayList<Producto>();
		}
		return listaProductos;
	}

	/**
	 * @param listaProductos the listaProductos to set
	 */
	public void setListaProductos(List<Producto> listaProductos) {
		this.listaProductos = listaProductos;
	}

	/**
	 * @return the vendedor
	 */
	public Vendedor getVendedor() {
		if (vendedor == null){
			vendedor = new Vendedor();
		}
		return vendedor;
	}

	/**
	 * @param vendedor the vendedor to set
	 */
	public void setVendedor(Vendedor vendedor) {
		this.vendedor = vendedor;
	}

	/**
	 * @param vendedorService the vendedorService to set
	 */
	public void setVendedorService(VendedorService vendedorService) {
		this.vendedorService = vendedorService;
	}

	/**
	 * @param ventasService the ventasService to set
	 */
	public void setVentasService(VentasService ventasService) {
		this.ventasService = ventasService;
	}

	/**
	 * @return the venta
	 */
	public Venta getVenta() {
		if (venta == null){
			venta = new Venta();
		}
		return venta;
	}

	/**
	 * @param venta the venta to set
	 */
	public void setVenta(Venta venta) {
		this.venta = venta;
	}

	/**
	 * @param detalleVenta the detalleVenta to set
	 */
	public void setDetalleVenta(List<DetalleVenta> detalleVenta) {
		this.detalleVenta = detalleVenta;
	}

	/**
	 * @return the detalleVenta
	 */
	public List<DetalleVenta> getDetalleVenta() {
		if (detalleVenta == null){
			detalleVenta = new ArrayList<DetalleVenta>();
		}
		return detalleVenta;
	}

	/**
	 * @return the prodToDelete
	 */
	public Long getProdToDelete() {
		return prodToDelete;
	}

	/**
	 * @param prodToDelete the prodToDelete to set
	 */
	public void setProdToDelete(Long prodToDelete) {
		this.prodToDelete = prodToDelete;
	}

}
